package com.vote.admin.service;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.vote.admin.util.OSSUtil;
import com.vote.admin.vo.param.VoteParam;
import com.vote.admin.vo.result.RecordResult;
import com.vote.admin.vo.result.VoteResult;
import com.vote.common.entity.VoteOption;
import com.vote.common.entity.VoteProject;
import com.vote.common.entity.VoteRecord;
import com.vote.common.entity.VoteUser;
import com.vote.common.enums.*;
import com.vote.common.returns.RespCode;
import com.vote.common.returns.RespEntity;
import com.vote.common.returns.RespTable;
import com.vote.common.service.VoteOptionService;
import com.vote.common.service.VoteProjectService;
import com.vote.common.service.VoteRecordService;
import com.vote.common.service.VoteUserService;
import com.vote.common.utils.TimeUtilCustomize;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Time;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class AdminVoteService {

    @Autowired
    private VoteUserService voteUserService;

    @Autowired
    private VoteProjectService voteProjectService;

    @Autowired
    private OSSUtil ossUtil;

    @Autowired
    private VoteOptionService voteOptionService;

    /**
     * 投票活动列表
     * @param page
     * @param limit
     * @param column
     * @param value
     * @return
     */
    public RespTable<List<VoteResult>> voteList(Integer page, Integer limit, String column, String value, HttpSession session) {
        VoteUser user = (VoteUser) session.getAttribute(AdminSessionEnum.ADMIN.getCode());
        QueryWrapper<VoteProject> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(user)) {
            if (user.getType().equals(1)) {
                queryWrapper.lambda().eq(VoteProject::getUserId, user.getId());
            }
        }
        //多条件模糊查询
        if (StringUtils.isNotBlank(column)) {
            queryWrapper.like(column, value);
        }
        queryWrapper.lambda().eq(VoteProject::getDeleted, 0)
                .orderByDesc(VoteProject::getId);

        IPage<VoteProject> iPage = new Page<>(page, limit);
        IPage<VoteProject> pg = voteProjectService.page(iPage, queryWrapper);

        List<VoteProject> records = pg.getRecords();
        List<VoteResult> voteResultList = Lists.newArrayList();
        if (CollectionUtil.isNotEmpty(records)) {
            for (VoteProject project : records) {
                //用户信息
                String username = UserTypeEnum.NO_USERNAME.getDesc();
                String name = UserTypeEnum.NO_NAME.getDesc();
                if (Objects.nonNull(project.getUserId())) {
                    VoteUser voteUser = voteUserService.getById(project.getUserId());
                    username = voteUser.getUsername();
                    name = voteUser.getName();
                }

                //数据组装
                VoteResult voteResult = VoteResult.builder()
                        .id(project.getId())
                        .username(username)
                        .projectName(project.getProjectName())
                        .projectDesc(project.getProjectDesc())
                        .projectImg(project.getProjectImg())
                        .projectPublic(VoteTypeEnum.getInstance(project.getProjectPublic()).getType())
                        .projectChoice(VoteChoiceEnum.getInstance(project.getProjectChoice()).getDesc())
                        .projectShow(VoteShowEnum.getInstance(project.getProjectShow()).getDesc())
                        .projectRule(project.getProjectRule())
                        .projectOption(project.getProjectOption())
                        .projectVote(project.getProjectVote())
                        .projectView(project.getProjectView())
                        .projectStatus(VoteStatusEnum.getInstance(project.getProjectStatus()).getStatus())
                        .projectStart(project.getProjectStart())
                        .projectEnd(project.getProjectEnd())
                        .build();

                voteResultList.add(voteResult);
            }
        }

        return new RespTable<>(RespCode.OK, voteResultList, pg.getTotal());
    }

    /**
     * OSS文件上传活动封面
     * */
    public RespEntity upload(MultipartFile file){
        String fileName = ossUtil.getFileName("vote/project/", file.getOriginalFilename());
        String url = ossUtil.getUrl(fileName);
        try {
            byte[] bytes = file.getBytes();
            ossUtil.upload(fileName, bytes);
            return new RespEntity(RespCode.SUCCESS, url);
        } catch (Exception e) {
            log.error("文件上传失败", e.getMessage());
            return new RespEntity(RespCode.SERVER_ERROR);
        }
    }

    /**
     * 发布投票活动
     * @param voteProject
     * @return
     */
    public RespEntity publishVote(VoteProject voteProject, HttpSession session) {
        VoteUser voteUser = (VoteUser) session.getAttribute(AdminSessionEnum.ADMIN.getCode());
        //时间处理
        if (StringUtils.isNotBlank(voteProject.getProjectStart())) {
            String[] split = voteProject.getProjectStart().split(" - ");
            voteProject.setProjectStart(split[0]);
            voteProject.setProjectEnd(split[1]);
            Date startTime = TimeUtilCustomize.parseStrToDate(TimeUtilCustomize.DATE_TIME_FORMAT, split[0]);
            Date endTime = TimeUtilCustomize.parseStrToDate(TimeUtilCustomize.DATE_TIME_FORMAT, split[1]);
            long now = new Date().getTime();
            if (startTime.getTime() > now) {
                voteProject.setProjectStatus(VoteStatusEnum.NOT_STARTED.getCode());
            }
            if (startTime.getTime() <= now && endTime.getTime() > now) {
                voteProject.setProjectStatus(VoteStatusEnum.IN_PROGRESS.getCode());
            }
            if (endTime.getTime() < now) {
                voteProject.setProjectStatus(VoteStatusEnum.FINISH.getCode());
            }
        }
        voteProject.setUserId(voteUser.getId());

        voteProjectService.save(voteProject);
        return new RespEntity(RespCode.SUCCESS, voteProject);
    }

    /**
     * 导出excel
     * @param response
     * @throws IOException
     */
    public void exportExcelAll(HttpServletResponse response, HttpSession session) {
        VoteUser user = (VoteUser) session.getAttribute(AdminSessionEnum.ADMIN.getCode());
        List<VoteResult> voteResultList = Lists.newArrayList();
        QueryWrapper<VoteProject> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(user)) {
            if (user.getType().equals(1)) {
                queryWrapper.lambda().eq(VoteProject::getUserId, user.getId());
            }
        }
        queryWrapper.lambda().eq(VoteProject::getDeleted, 0);

        List<VoteProject> voteProjectList = voteProjectService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(voteProjectList)) {
            for (VoteProject project : voteProjectList) {
                //用户信息
                String username = UserTypeEnum.NO_USERNAME.getDesc();
                String name = UserTypeEnum.NO_NAME.getDesc();
                if (Objects.nonNull(project.getUserId())) {
                    VoteUser voteUser = voteUserService.getById(project.getUserId());
                    username = voteUser.getUsername();
                    name = voteUser.getName();
                }

                //数据组装
                VoteResult voteResult = VoteResult.builder()
                        .id(project.getId())
                        .username(username)
                        .projectName(project.getProjectName())
                        .projectDesc(project.getProjectDesc())
                        .projectImg(project.getProjectImg())
                        .projectPublic(VoteTypeEnum.getInstance(project.getProjectPublic()).getType())
                        .projectChoice(VoteChoiceEnum.getInstance(project.getProjectChoice()).getDesc())
                        .projectShow(VoteShowEnum.getInstance(project.getProjectShow()).getDesc())
                        .projectRule(project.getProjectRule())
                        .projectOption(project.getProjectOption())
                        .projectVote(project.getProjectVote())
                        .projectView(project.getProjectView())
                        .projectStatus(VoteStatusEnum.getInstance(project.getProjectStatus()).getStatus())
                        .projectStart(project.getProjectStart())
                        .projectEnd(project.getProjectEnd())
                        .build();

                voteResultList.add(voteResult);
            }
        }

        ExportParams exportParams = new ExportParams("投票活动数据信息", "投票活动");
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, VoteResult.class, voteResultList);
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-disposition","attachment;filename=vote_"+new Date().getTime()+".xls");
        try {
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            log.error("导出excel表格失败", e.getMessage());
        }
    }

    /**
     * 编辑活动信息
     * @param voteParam
     * @return
     */
    public RespEntity updateVote(VoteParam voteParam) {

        //数据组装
        VoteProject voteProject = VoteProject.builder()
                .id(voteParam.getId())
                .projectName(voteParam.getProjectName())
                .projectDesc(voteParam.getProjectDesc())
                .projectImg(voteParam.getProjectImg())
                .projectPublic(VoteTypeEnum.getByDesc(voteParam.getProjectPublic()).getCode())
                .projectChoice(VoteChoiceEnum.getByDesc(voteParam.getProjectChoice()).getCode())
                .projectShow(VoteShowEnum.getByDesc(voteParam.getProjectShow()).getCode())
                .projectRule(voteParam.getProjectRule())
                .build();

        //时间处理
        if (StringUtils.isNotBlank(voteParam.getProjectEnd())) {
            String[] split = voteParam.getProjectEnd().split(" - ");
            voteProject.setProjectStart(split[0]);
            voteProject.setProjectEnd(split[1]);
            Date startTime = TimeUtilCustomize.parseStrToDate(TimeUtilCustomize.DATE_TIME_FORMAT, split[0]);
            Date endTime = TimeUtilCustomize.parseStrToDate(TimeUtilCustomize.DATE_TIME_FORMAT, split[1]);
            long now = new Date().getTime();
            if (startTime.getTime() > now) {
                voteProject.setProjectStatus(VoteStatusEnum.NOT_STARTED.getCode());
            }
            if (startTime.getTime() <= now && endTime.getTime() > now) {
                voteProject.setProjectStatus(VoteStatusEnum.IN_PROGRESS.getCode());
            }
            if (endTime.getTime() < now) {
                voteProject.setProjectStatus(VoteStatusEnum.FINISH.getCode());
            }
        }

        voteProjectService.updateById(voteProject);

        return new RespEntity(RespCode.SUCCESS);
    }

    /**
     * 删除投票活动信息
     * @param id
     * @return
     */
    public RespEntity deleteVote(Integer id) {
        VoteProject voteProject = VoteProject.builder()
                .id(id)
                .deleted(1)
                .build();

        voteProjectService.updateById(voteProject);

        return new RespEntity(RespCode.SUCCESS);
    }

    /**
     * 选项列表
     * @param page
     * @param limit
     * @param content
     * @param id
     * @return
     */
    public RespTable<List<VoteOption>> optionList(Integer page, Integer limit, String content, Integer id) {
        QueryWrapper<VoteOption> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(content)) {
            queryWrapper.lambda().like(VoteOption::getOptionName, content);
        }
        queryWrapper.lambda().eq(VoteOption::getDeleted, 0)
                .eq(VoteOption::getProjectId, id)
                .orderByDesc(VoteOption::getId);

        IPage<VoteOption> iPage = new Page<>(page, limit);
        IPage<VoteOption> pg = voteOptionService.page(iPage, queryWrapper);

        return new RespTable<>(RespCode.OK, pg.getRecords(), pg.getTotal());
    }

    /**
     * OSS文件上传选项图片
     * */
    public RespEntity optionUpload(MultipartFile file){
        String fileName = ossUtil.getFileName("vote/option/", file.getOriginalFilename());
        String url = ossUtil.getUrl(fileName);
        try {
            byte[] bytes = file.getBytes();
            ossUtil.upload(fileName, bytes);
            return new RespEntity(RespCode.SUCCESS, url);
        } catch (Exception e) {
            log.error("文件上传失败", e.getMessage());
            return new RespEntity(RespCode.SERVER_ERROR);
        }
    }

    /**
     * 新增选项
     * @param voteOption
     * @return
     */
    public RespEntity insertOption(VoteOption voteOption) {
        voteOptionService.save(voteOption);

        //更新活动表数据
        VoteProject voteProject = voteProjectService.getById(voteOption.getProjectId());
        Integer projectOption = voteProject.getProjectOption();
        projectOption += 1;
        voteProject.setProjectOption(projectOption);
        voteProjectService.updateById(voteProject);

        return new RespEntity(RespCode.SUCCESS);
    }

    /**
     * 编辑选项
     * @param voteOption
     * @return
     */
    public RespEntity updateOption(VoteOption voteOption) {
        voteOptionService.updateById(voteOption);
        return new RespEntity(RespCode.SUCCESS);
    }


    /**
     * 删除选项
     * @param id
     * @return
     */
    public RespEntity deleteOption(Integer id) {
        VoteOption voteOption = VoteOption.builder()
                .id(id)
                .deleted(1)
                .build();

        voteOptionService.updateById(voteOption);

        //更新活动表数据
        voteOption = voteOptionService.getById(id);
        VoteProject voteProject = voteProjectService.getById(voteOption.getProjectId());
        Integer projectOption = voteProject.getProjectOption();
        projectOption -= 1;
        voteProject.setProjectOption(projectOption);
        voteProjectService.updateById(voteProject);

        return new RespEntity(RespCode.SUCCESS);
    }

}
